package cn.cai.service.impl;

import cn.cai.exceptionHandler.GuliException;
import cn.cai.service.OSSService;
import cn.cai.utils.MinioAdmin;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
public class OSSServiceImpl implements OSSService {
    /**
     * 实现文件上传的服务方法
     * @param file 要上传的文件对象
     * @return url地址
     */
    @Override
    public String uploadFileAvatar(MultipartFile file) {
        MinioClient minioClient = null;
        InputStream inputStream = null;
        //返回文件的真实文件名
        StringBuffer originalFilename = new StringBuffer();
        originalFilename.append(UUID.randomUUID().toString().replace("-","").toUpperCase());
        originalFilename.append(file.getOriginalFilename());
        try {
            inputStream = file.getInputStream();
            minioClient = MinioClient.builder()
                    .endpoint(MinioAdmin.ENDPOINT)
                    .credentials(MinioAdmin.ACCESSKEY,MinioAdmin.SECRETKEY)
                    .build();
            //上传
//            minioClient.putObject("photo",originalFilename.toString(),inputStream,new PutObjectOptions(file.getSize(),0));
            minioClient.putObject(
                    PutObjectArgs
                            .builder()
                            .bucket("photo")
                            .stream(inputStream,file.getSize(),-1)
                            .object(originalFilename.toString())
                            .build());
            inputStream.close();
            //得到url
//            return minioClient.presignedGetObject("photo", originalFilename.toString());
            return minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket("photo")
                            .object(originalFilename.toString())
                            .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 返回课程封面的默认路径
     * @return 默认封面路径
     */
    @Override
    public String returnDefaultCover() {
        try {
            MinioClient minioClient = MinioClient
                    .builder()
                    .endpoint(MinioAdmin.ENDPOINT)
                    .credentials(MinioAdmin.ACCESSKEY,MinioAdmin.SECRETKEY)
                    .build();
//            String url = minioClient.presignedGetObject("cover", "默认封面.jpeg",60 * 60 * 24 );
            return minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .bucket("cover")
                            .method(Method.GET)
                            .object("默认封面.jpg")
                            .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
            throw new GuliException(20001,"服务器出错");
        }

    }

    @Override
    public String uploadCover(MultipartFile file) {
        MinioClient minioClient = null;
        InputStream inputStream = null;
        //返回文件的真实文件名
        StringBuffer originalFilename = new StringBuffer();
        originalFilename.append(UUID.randomUUID().toString().replace("-","").toUpperCase());
        originalFilename.append(file.getOriginalFilename());
        try {
            inputStream = file.getInputStream();
            minioClient = MinioClient.builder()
                    .endpoint(MinioAdmin.ENDPOINT)
                    .credentials(MinioAdmin.ACCESSKEY,MinioAdmin.SECRETKEY)
                    .build();
            //上传
//            minioClient.putObject("cover",originalFilename.toString(),inputStream,new PutObjectOptions(file.getSize(),0));
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket("cover")
                            .stream(inputStream, file.getSize(), -1)
                            .object(originalFilename.toString())
                            .build()
            );
            inputStream.close();
            //得到url
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket("cover")
                            .object(originalFilename.toString())
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String getDefaultAvatar() {
        MinioClient minioClient = MinioClient.builder()
                .endpoint(MinioAdmin.ENDPOINT)
                .credentials(MinioAdmin.ACCESSKEY, MinioAdmin.SECRETKEY)
                    .build();
        try {
            String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket("photo")
                    .object("默认头像.jpg")
                    .build());
            return url;
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用minio java JDK 获取指定资源的url地址，请求方式为get
     * @param bucketName 资源所在的桶
     * @param object 资源所在的对象
     * @return 资源对应的url请求地址（请求方式为get）
     */
    @Override
    public String objectInTheBucket(String bucketName, String object) {
        try {

            //建立minio客户端
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(MinioAdmin.ENDPOINT)
                    .credentials(MinioAdmin.ACCESSKEY,MinioAdmin.SECRETKEY)
                    .build();
            // 获取桶中的对象集合，比较是否含有改对象
            Set<String> objectList = new HashSet<>();
            //获得桶中的所有对象集合
            for (Result<Item> itemResult : minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build())) {
                objectList.add(itemResult.get().objectName());
            }
            for (String tempObject:objectList){
                if (tempObject.equals(object)){
                    //所需的资源存在
                    //返回请求该资源所需的get类型的url
                    return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(object)
                            .build());

                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new GuliException(20001,"服务器异常");
        }
        return null;
    }
}
